package com.xm.thread.wait2notify;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Slf4j
public class Test {
    public static void main(String[] args) {
        // 手动 wait 和 notify
        WaitToNotify01 waitToNotify01 = new WaitToNotify01();
        waitToNotify01.put(100);
        int data = waitToNotify01.get();
        log.info("data = {}", data);

        // 使用Lock + Condition（精细控制）
        WaitToNotify02 waitToNotify02 = new WaitToNotify02();
        waitToNotify02.put(100);
        int data2 = waitToNotify02.get();
        log.info("data2 = {}", data2);

        // 使用BlockingQueue（生产者-消费者最佳实践）
        WaitToNotify03 waitToNotify03 = new WaitToNotify03();
        new Thread(waitToNotify03.producer).start();
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        new Thread(waitToNotify03.consumer).start();

        // 使用CountDownLatch（一次性等待）
        WaitToNotify04 waitToNotify04 = new WaitToNotify04();
        try {
            new Thread(waitToNotify04.worker).start();
            new Thread(waitToNotify04.worker).start();
            new Thread(waitToNotify04.worker).start();

            waitToNotify04.latch.await();
            log.info("所有工人已准备就绪！");
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        // 使用Semaphore（资源配额控制）
        WaitToNotify05 waitToNotify05 = new WaitToNotify05();
        ExecutorService executor = Executors.newFixedThreadPool(100);
        for (int i = 0; i < 100; i++) {
            executor.execute(waitToNotify05.countTask);
        }
        executor.shutdown();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        log.info("atomicInt = {}", waitToNotify05.atomicInt);
    }
}
